﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.IO;
using System.Threading.Tasks;
using System.Collections.Concurrent;
using AlertSystem.Business;
using PluggableModulesInterface;
using System.Reflection;
using Utils;
using System.Data.SqlClient;

namespace AlertSystem.UI
{
    public partial class FrmMain : Form
    {
        #region declare
        private static int WM_QUERYENDSESSION = 0x11;
        private static bool systemShutdown = false;
        #endregion declare

        public FrmMain()
        {
            InitializeComponent();
        }

        private void InitNotifierSql()
        {
            SQLNotifier notifyWarning_System = new SQLNotifier("Warning_System", "System_Id");
            notifyWarning_System.Notify += new SQLNotifier.OnNotify(Warning_System.ReloadData);
            notifyWarning_System.Start();

            SQLNotifier notifyWarning_Type = new SQLNotifier("Warning_Type", "WarningType");
            notifyWarning_Type.Notify += new SQLNotifier.OnNotify(Warning_Type.ReloadData);
            notifyWarning_Type.Start();

            SQLNotifier notifyWarning_System_Type_Account = new SQLNotifier("Warning_System_Type_Account", "Account_Id");
            notifyWarning_System_Type_Account.Notify += new SQLNotifier.OnNotify(Warning_System_Type_Account.ReloadData);
            notifyWarning_System_Type_Account.Start();

            SQLNotifier notifyWarning_Organization = new SQLNotifier("Warning_Organization", "Organization_Id");
            notifyWarning_Organization.Notify += new SQLNotifier.OnNotify(Warning_Organization.ReloadData);
            notifyWarning_Organization.Start();

            SQLNotifier notifyWarning_Account = new SQLNotifier("Warning_Account", "Account_Id");
            notifyWarning_Account.Notify += new SQLNotifier.OnNotify(Warning_Account.ReloadData);
            notifyWarning_Account.Start();

            SQLNotifier notifyWarning_Method_Type = new SQLNotifier("Warning_Method_Type", "Method_Type");
            notifyWarning_Method_Type.Notify += new SQLNotifier.OnNotify(Warning_Method_Type.ReloadData);
            notifyWarning_Method_Type.Start();

            SQLNotifier notifyWarning_Method = new SQLNotifier("Warning_Method", "Method_Id");
            notifyWarning_Method.Notify += new SQLNotifier.OnNotify(Warning_Method.ReloadData);
            notifyWarning_Method.Start();
        }

        private void FrmMain_Load(object sender, EventArgs e)
        {
            try
            {
                EnableSystem(false);
                //FrmProgressBar.Show("Starting program...");
                this.FormClosing += new FormClosingEventHandler(FrmMain_FormClosing);
                //InitNotifierSql();
                //PluggableManage.Init();
                //FrmProgressBar.Hide();
            }
            catch (Exception ex)
            {
                FrmProgressBar.Hide();
                if (ex.Message.Contains("The server was not found or was not accessible"))
                {
                    MessageBox.Show("The server was not found or was not accessible.\n Program will be closed.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    Application.Exit();
                }
                else
                {
                    MessageBox.Show(ex.ToString());
                }
            }
        }

        #region Notify Icon function
        void FrmMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (systemShutdown)
            {
                this.Show();
                systemShutdown = false;
                if (MessageBox.Show("Before system shutdown or reboot, must be backup data.\nDo you want backup data and close program now?", "Confirm", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == DialogResult.Yes)
                {
                    FrmProgressBar.Show("Backing-up data and exiting...");
                    StaticThreadManage.Stop();
                    FrmProgressBar.Hide();
                    e.Cancel = false;
                }
                else
                {
                    e.Cancel = true;
                }
                return;
            }
            if (e.CloseReason == CloseReason.ApplicationExitCall) return;
            e.Cancel = true;
            this.Hide();
        }

        private void notifyIcon_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (!this.Visible)
                this.Show();
        }

        private void cmnShow_Click(object sender, EventArgs e)
        {
            if (!this.Visible)
                this.Show();
        }

        private void mnExit_Click(object sender, EventArgs e)
        {
            try
            {
                if (MessageBox.Show("Are you sure want to exit?", "Confirm", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == DialogResult.Yes)
                {
                    FrmProgressBar.Show("Backup data and exiting...");
                    StaticThreadManage.Exit();
                    FrmProgressBar.Hide();
                    Application.Exit();
                }
            }
            catch (Exception ex)
            {
                FrmProgressBar.Hide();
                MessageBox.Show(ex.ToString());
            }
        }
        #endregion Notify Icon function
        
        #region Event
        public void SetControl(string action)
        {
            if (action == "Start")
            {
                mnStartStop.Text = "Stop";
            }
            else
            {
                mnStartStop.Text = "Start";
            }
        }

        public void SetMenuStartStopEnable()
        {
            if (PluggableManage.GetListOfModule().Count > 0) mnStartStop.Enabled = true;
            else mnStartStop.Enabled = false;
        }

        private void mnStartStop_Click(object sender, EventArgs e)
        {
            if (mnStartStop.Text == "Start")
            {
                Start();
                SetControl(mnStartStop.Text);
            }
            else
            {
                if (MessageBox.Show("Are you sure want to stop all running module?", "Confirm", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == System.Windows.Forms.DialogResult.Yes)
                {
                    Stop();
                    SetControl(mnStartStop.Text);
                }
            }
            foreach (Form f in this.MdiChildren)
            {
                if (f.Name == typeof(FrmMethodList).Name)
                {
                    ((FrmMethodList)f).LoadData();
                }
            }
        }

        private void mnMethod_Click(object sender, EventArgs e)
        {
            FrmMethodList frm = new FrmMethodList();
            bool found = false;
            foreach (Form f in this.MdiChildren)
            {
                if (f.Name == frm.Name)
                {
                    f.Show();
                    found = true;
                }
            }
            if (!found)
            {
                frm.MdiParent = this;
                frm.WindowState = FormWindowState.Maximized;
                frm.Show();
            }
        }
        
        protected override void WndProc(ref System.Windows.Forms.Message m)
        {
            if (m.Msg == WM_QUERYENDSESSION)
            {
                //MessageBox.Show("queryendsession: this is a logoff, shutdown, or reboot");
                systemShutdown = true;
            }

            // If this is WM_QUERYENDSESSION, the closing event should be
            // raised in the base WndProc.
            base.WndProc(ref m);

        } //WndProc
        #endregion Event

        private void Start()
        {
            try
            {
                FrmProgressBar.Show("Starting...");
                StaticThreadManage.Start();
                PluggableManage.Start();
                FrmProgressBar.Hide();
            }
            catch (Exception ex)
            {
                FrmProgressBar.Hide();
                MessageBox.Show(ex.ToString());
            }
        }

        private void Stop()
        {
            try
            {
                FrmProgressBar.Show("Stopping...");
                StaticThreadManage.Stop();
                PluggableManage.Stop();
                FrmProgressBar.Hide();
            }
            catch (Exception ex)
            {
                FrmProgressBar.Hide();
                MessageBox.Show(ex.ToString());
            }
        }

        private void EnableSystem(bool enableSystem)
        {
            try
            {
                mnConnect.Enabled = !enableSystem;
                mnConnectionConfig.Enabled = !enableSystem;
                mnStartStop.Enabled = enableSystem;
                mnListManagement.Enabled = enableSystem;
                if (enableSystem)
                {
                    mnConnect.Text = "Connected";
                    FrmProgressBar.Show("Initializing...");
                    this.FormClosing += new FormClosingEventHandler(FrmMain_FormClosing);
                    InitNotifierSql();
                    PluggableManage.Init(AppSetting.AppModulesPath);
                    SetMenuStartStopEnable();
                    FrmProgressBar.Hide();
                }
            }
            catch (Exception)
            {
                throw;
            }
        }

        private void mnConnect_Click(object sender, EventArgs e)
        {
            try
            {
                FrmProgressBar.Show("Connecting...");
                using (SqlConnection con = AppSetting.GetConnection())
                {
                    if (con.State == ConnectionState.Open)
                    {
                        EnableSystem(true);
                    }
                    else if (con.State == ConnectionState.Broken || con.State == ConnectionState.Closed)
                    {
                        EnableSystem(false);
                    }
                }
                FrmProgressBar.Hide();
            }
            catch (Exception ex)
            {
                FrmProgressBar.Hide();
                if (ex.Message.Contains("The server was not found or was not accessible"))
                {
                    MessageBox.Show("The server was not found or was not accessible.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                }
                else if (ex.Message.Contains("Cannot open database"))
                {
                    MessageBox.Show("Cannot open database.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                }
                else if (ex.Message.Contains("Login failed for user"))
                {
                    MessageBox.Show("UserID or password not correct.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                }
                else
                {
                    MessageBox.Show(ex.ToString());
                }
            }
        }

        private void mnConnectionConfig_Click(object sender, EventArgs e)
        {
            FrmConnectionConfig frm = new FrmConnectionConfig();
            frm.ShowDialog();
        }
    }
}